package com.yun.zf.system.redis;

import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedissonUtils {
    @Autowired
    private RedissonClient redissonClient;

    /**
     * `
     * 获取字符串对象
     *
     * @param objectName
     * @return
     */
    public <T> RBucket<T> getRBucket(String objectName) {
        RBucket<T> bucket = redissonClient.getBucket(objectName);
        return bucket;
    }

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */

    public Object getCacheObject(String key) {

        return key == null ? null : (Object) redissonClient.getBucket(key).get();

    }


    public boolean setCacheObject(String key, Object value) {
        try {
            RBucket<Object> bucket = redissonClient.getBucket(key);
            bucket.set(value);
            return true;
        } catch (Exception e) {

            e.printStackTrace();

            return false;

        }
    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */

    public boolean setCacheObject(String key, Object value, long time, TimeUnit timeUnit) {

        try {

            if (time > 0) {

                RBucket<Object> bucket = redissonClient.getBucket(key);
                bucket.set(value, time, timeUnit);

            } else {
                setCacheObject(key, value);
            }
            return true;
        } catch (Exception e) {

            e.printStackTrace();

            return false;

        }

    }

    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */

    @SuppressWarnings("unchecked")

    public void deleteObject(String key) {
        RBucket<Object> bucket = redissonClient.getBucket(key);
        bucket.delete();
    }


    /**
     * 获取Map对象
     *
     * @param objectName
     * @return
     */
    public <K, V> RMap<K, V> getRMap(String objectName) {
        RMap<K, V> map = redissonClient.getMap(objectName);
        return map;
    }

    /**
     * 获取有序集合
     *
     * @param objectName
     * @return
     */
    public <V> RSortedSet<V> getRSortedSet(String objectName) {
        RSortedSet<V> sortedSet = redissonClient.getSortedSet(objectName);
        return sortedSet;
    }

    /**
     * 获取集合
     *
     * @param objectName
     * @return
     */
    public <V> RSet<V> getRSet(String objectName) {
        RSet<V> rSet = redissonClient.getSet(objectName);
        return rSet;
    }

    /**
     * 获取列表
     *
     * @param objectName
     * @return
     */
    public <V> RList<V> getRList(String objectName) {
        RList<V> rList = redissonClient.getList(objectName);
        return rList;
    }

    /**
     * 获取队列
     *
     * @param objectName
     * @return
     */
    public <V> RQueue<V> getRQueue(String objectName) {
        RQueue<V> rQueue = redissonClient.getQueue(objectName);
        return rQueue;
    }

    /**
     * 获取双端队列
     *
     * @param objectName
     * @return
     */
    public <V> RDeque<V> getRDeque(String objectName) {
        RDeque<V> rDeque = redissonClient.getDeque(objectName);
        return rDeque;
    }


    /**
     * 加锁
     *
     * @return
     */
    public void lock(String lockKey) {
        redissonClient.getLock(lockKey).lock();
    }

    /**
     * 释放锁
     */
    public void unLock(String lockKey) {
        redissonClient.getLock(lockKey).unlock();
    }

    /**
     * 带超时的加锁
     *
     * @param lockKey
     * @param tomeout 秒为单位
     */
    public void lock(String lockKey, Long tomeout) {
        redissonClient.getLock(lockKey).lock(tomeout, TimeUnit.SECONDS);
    }

    /**
     * 带超市的加锁
     *
     * @param lockKey
     * @param unit    时间单位
     * @param tomeout
     */
    public void lock(String lockKey, TimeUnit unit, Long tomeout) {
        redissonClient.getLock(lockKey).lock(tomeout, unit);
    }


    /**
     * 尝试获取锁
     *
     * @param lockKey
     * @return
     */
    public boolean tryLock(String lockKey) {
        return redissonClient.getLock(lockKey).tryLock();
    }

    /**
     * 尝试获取锁
     *
     * @param lockKey
     * @param timeout 尝试等待多少秒时间
     * @return
     * @throws InterruptedException
     */
    public boolean tryLock(String lockKey, Long timeout) throws InterruptedException {
        return redissonClient.getLock(lockKey).tryLock(timeout, TimeUnit.SECONDS);
    }


    /**
     * @param lockKey
     * @param unit      时间单位
     * @param waitTime  最多等待多久时间
     * @param leaseTime 上锁后多久释放
     * @return
     */
    public boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) throws InterruptedException {
        return redissonClient.getLock(lockKey).tryLock(waitTime, leaseTime, unit);
    }


    public void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.unlock();
    }
}
